using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ProtectThePie;

namespace ProtectThePieWP7.AdditionalClasses
{
    public enum GameStringType
    {
        FadeOut,
        FadeIn,
        FadeInFadeOut,
        FloatUp,
        FloatUpFadeOut,
        FloatupFadeInFadeOut
    }

    public enum GameStringState
    {
        Idle,
        FadeIn,
        FadeOut,
        finish
    }

    public class GameString
    {
        private GameStringType type;
        private GameStringState state;

        private string text;
        private bool fadeIn = false;
        private bool fadeOut = false;
        private bool floatUp = false;
        private Vector2 position;
        private SpriteFont textFont;
        private Color color;
        private Color drawingColor;
        private Color shadowColor;
        private bool shadow;
        private Vector2 origin;

        private TimeSpan fadeInTime;
        private TimeSpan idleTime;
        private TimeSpan fadeOutTime;

        private DateTime creationTime;
        private TimeSpan lifeTime;

        public GameString(string text, Vector2 position, GameStringType type, SpriteFont textFont, Color color, bool shadow)
        {
            this.type = type;
            this.text = text;
            this.position = position;
            this.textFont = textFont;
            this.creationTime = DateTime.UtcNow;
            this.color = color;
            this.drawingColor = color;
            this.shadowColor = Color.White;
            this.shadow = shadow;
            Vector2 textSize = textFont.MeasureString(text);
            this.origin = new Vector2(textSize.X / 2, textSize.Y / 2);

            this.fadeInTime = new TimeSpan(0, 0, 0, 0, 500);
            this.idleTime = new TimeSpan(0, 0, 0, 1);
            this.fadeOutTime = new TimeSpan(0, 0, 0, 0, 500);

            switch (type)
            {
                case GameStringType.FadeIn:
                    fadeIn = true;
                    this.fadeOutTime = new TimeSpan(0, 0, 0);
                    break;
                case GameStringType.FadeInFadeOut:
                    fadeIn = true;
                    this.fadeInTime = new TimeSpan(0, 0, 0, 0, 500);
                    this.idleTime = new TimeSpan(0, 0, 0, 3);
                    this.fadeOutTime = new TimeSpan(0, 0, 0, 0, 500);
                    fadeOut = true;
                    break;
                case GameStringType.FadeOut:
                    fadeOut = true;
                    this.fadeInTime = new TimeSpan(0, 0, 0);
                    this.idleTime = new TimeSpan(0, 0, 0, 0, 200);
                    break;
                case GameStringType.FloatUp:
                    floatUp = true;
                    this.fadeInTime = new TimeSpan(0, 0, 0);
                    this.fadeOutTime = new TimeSpan(0, 0, 0);
                    break;
                case GameStringType.FloatupFadeInFadeOut:
                    fadeIn = true;
                    fadeOut = true;
                    floatUp = true;
                    this.fadeInTime = new TimeSpan(0, 0, 0, 0, 200);
                    this.idleTime = new TimeSpan(0, 0, 0, 0, 200);
                    break;
                case GameStringType.FloatUpFadeOut:
                    fadeOut = true;
                    floatUp = true;
                    this.fadeInTime = new TimeSpan(0, 0, 0);
                    this.idleTime = new TimeSpan(0, 0, 0, 0, 200);
                    break;
            }

            if (fadeIn) state = GameStringState.FadeIn;
            else state = GameStringState.Idle;
        }

        public GameString(string text, Vector2 position, int fadein, int idle, int fadeout, SpriteFont textFont, Color color, bool shadow)
        {
            this.text = text;
            this.position = position;
            this.textFont = textFont;
            this.creationTime = DateTime.UtcNow;
            this.color = color;
            this.drawingColor = color;
            this.shadowColor = Color.White;
            this.shadow = shadow;
            Vector2 textSize = textFont.MeasureString(text);
            this.origin = new Vector2(textSize.X / 2, textSize.Y / 2);

            this.fadeInTime = new TimeSpan(0, 0, 0, 0, fadein);
            this.idleTime = new TimeSpan(0, 0, 0, idle);
            this.fadeOutTime = new TimeSpan(0, 0, 0, 0, fadeout);

            this.fadeIn = true;
            this.fadeOut = true;

            if (fadeIn) state = GameStringState.FadeIn;
            else state = GameStringState.Idle;
        }

        /// <summary>
        /// Updates Game String
        /// </summary>
        /// <param name="TotalGameTime">Total Game Time</param>
        /// <returns>returns false if finished</returns>
        public bool Update()
        {
            lifeTime = DateTime.UtcNow.Subtract(creationTime);

            if (floatUp)
            {
                Vector2Add.Add(ref position, 0, -0.8f);
            }

            switch (state)
            {
                case GameStringState.FadeIn:
                    if (lifeTime > fadeInTime)
                    {
                        drawingColor = color;
                        shadowColor = Color.White;
                        state = GameStringState.Idle;
                    }
                    else
                    {
                        float ratio = (float)(lifeTime.TotalMilliseconds / fadeInTime.TotalMilliseconds);                       
                        drawingColor = new Color((int)(color.R * ratio), (int)(color.G * ratio), (int)(color.B * ratio), (int)(255 * ratio));

                        if (shadow)
                        {
                            int shadowAlphaSample = (int)(255 * ratio / 3);
                            int shadowColorSample = (int)(255 * ratio / 2);
                            shadowColor = new Color(shadowColorSample, shadowColorSample, shadowColorSample, shadowAlphaSample);
                        }
                    }
                    return true;
                case GameStringState.Idle:
                    if (lifeTime > fadeInTime + idleTime) 
                    {
                        if (fadeOut) state = GameStringState.FadeOut;
                        else state = GameStringState.finish;
                    }
                    return true;
                case GameStringState.FadeOut:
                    if (lifeTime > fadeInTime + idleTime + fadeOutTime) state = GameStringState.finish;
                    else
                    {
                        float ratio = (1 - (float)(lifeTime.TotalMilliseconds - fadeInTime.TotalMilliseconds - idleTime.TotalMilliseconds) / (float)fadeOutTime.TotalMilliseconds);
                        drawingColor = new Color((int)(color.R * ratio), (int)(color.G * ratio), (int)(color.B * ratio), (int)(255 * ratio));

                        if (shadow)
                        {
                            int shadowColorSample = (int)(255 * ratio / 3);
                            shadowColor = new Color(shadowColorSample, shadowColorSample, shadowColorSample, shadowColorSample);
                        }
                    }
                    return true;
                case GameStringState.finish:
                    return false;
                default:
                    return false;
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            if (shadow)
            {
                spriteBatch.DrawString(textFont, text, Vector2.Add(position, new Vector2(2, 2)), shadowColor, 0.0f, origin, 1.0f, SpriteEffects.None, 1);
            }
            spriteBatch.DrawString(textFont, text, position, drawingColor, 0.0f, origin, 1.0f, SpriteEffects.None, 1);

        }
    }
}
